home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 December / DPPCPRO1205.ISO / Essentials / Programming / Basic4GL / Setup Basic4GL v2.3.1.exe / $INSTDIR / Programs / Heightmap6.gb < prev    next >
Encoding:
Text File  |  2005-07-29  |  7.5 KB  |  208 lines

  1. ' Heightmap demo 6
  2. '
  3. ' Flying around!
  4. '
  5. const heightScale# = 10 ' Height map scale factor
  6. const texScale# = 0.1   ' Number of textures per grid square
  7. const viewRange = 50    ' Number of cells visible
  8. dim xSize, ySize
  9. dim xMask, yMask        ' bitmasks to apply to X and Y coordinates
  10. dim file                ' File handle
  11. dim x, y                ' Working variables
  12. dim texture             ' OpenGL texture handle for our texture
  13. dim tx#, ty#            ' Texture coordinates
  14. dim a#(2), b#(2), c#(2), d#(2), norm#(2) ' Temporary vectors used for lighting
  15. dim intensity#
  16. dim cameraMatrix#(3)(3) ' Camera position
  17. dim cameraPos#(3)
  18. dim startX, startY, start#(3)      ' Start of viewable grid range
  19. dim inputX#, inputY#
  20.  
  21. goto Start
  22.  
  23. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  24. ' Routines
  25. CheckError:
  26.     ' Check for file error
  27.     if FileError () <> "" then
  28.         print FileError ()
  29.         CloseFile (file)
  30.         end
  31.     endif
  32.     return
  33.  
  34. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  35. ' Main program stars here    
  36. Start:
  37.  
  38. ' Open file
  39. file = OpenFileRead ("Files\Hills01.dat")
  40.     ' Note: Basic4GL will only open files in the "files" subfolder of the folder
  41.     '       where the program is saved.
  42. gosub CheckError
  43.  
  44. ' Read X and Y size
  45. xSize = Val (ReadLine (file))
  46. ySize = Val (ReadLine (file))
  47. gosub CheckError
  48.  
  49. ' Now that size is known, we can dim our 2D array
  50. dim h#(xSize - 1)(ySize - 1)        
  51. xMask = xSize - 1
  52. yMask = ySize - 1
  53.  
  54. for y = 0 to ySize - 1
  55.     for x = 0 to xSize - 1
  56.         h#(x)(y) = val (ReadText (file, true)) * heightScale#
  57.         gosub CheckError
  58.     next
  59. next          
  60. CloseFile (file)
  61.  
  62. ' Create light map
  63. dim lightSource#(2)
  64. lightSource# = vec3(0, -1, 0)           ' Light shines straight down.
  65. lightSource# = Normalize (lightSource#) ' Light source must be length 1
  66.  
  67. ' Create light map
  68. dim l# (xSize - 1)(ySize - 1)
  69. for x = 0 to xSize - 1
  70.     for y = 0 to ySize - 1
  71.         a# = vec3 (x,   h#(x)(y),                             y)
  72.         b# = vec3 (x+1, h#((x+1) and xMask)(y),               y)
  73.         c# = vec3 (x  , h#(x              )((y+1) and yMask), y+1)        
  74.         d# = vec3 (x+1, h#((x+1) and xMask)((y+1) and yMask), y+1)
  75.  
  76.         norm# = Normalize (CrossProduct (d# - a#, b# - c#))        
  77.  
  78.         intensity# = norm# * -lightSource#
  79.  
  80.         intensity# = intensity# * intensity# * intensity#
  81.         if intensity# < 0.2 then intensity# = 0.2 endif
  82.             
  83.         l#(x)(y) = intensity#
  84.     next
  85. next
  86.  
  87. ' Load texture file 
  88. texture = LoadMipmapTexture ("textures\00005.jpg")
  89.  
  90. ' Enable texture mapping, and bind our texture
  91. glEnable (GL_TEXTURE_2D)
  92. glBindTexture (GL_TEXTURE_2D, texture)
  93.  
  94. ' Setup fog
  95. glEnable (GL_FOG)
  96. glFogi (GL_FOG_MODE, GL_LINEAR)
  97. glFogf (GL_FOG_START, viewRange * .3)
  98. glFogf (GL_FOG_END, viewRange * .8)
  99. glFogfv (GL_FOG_COLOR, vec4 (0, 0, 0, 1))
  100.  
  101. glEnable (GL_CULL_FACE)   
  102. ' "Cull face" is a speed optimisation that tells OpenGL not to draw any
  103. ' polygons that are facing away from the camera.
  104. ' The order that the polygon points are drawn in determines which way
  105. ' the polygon is said to be facing.
  106. ' When the polygon is facing towards the camera, all its points must
  107. ' be in anti-clockwise order.
  108.  
  109. ' Set camera's start position
  110. cameraMatrix# = MatrixRotateY (45)
  111. cameraPos# = vec4 (0, 10, 0, 1)
  112. ' The camera is a little bit complicated to explain.
  113. ' We represent it as a rotation matrix, and a position vector.
  114.  
  115. ' Text instructions
  116. TextMode (TEXT_OVERLAID)
  117. locate 4, 4: print "Use the arrow keys to fly around"
  118.  
  119. while true
  120.     
  121.     ' Clear the screen
  122.     glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
  123.         
  124.     ' Setup camera transformation
  125.  
  126.     ' To draw the scene relative to the camera, we create a rotation and translation 
  127.     ' matrix that describes the CAMERA RELATIVE TO THE SCREEN
  128.     ' We then INVERT the matrix, which describes the SCREEN RELATIVE TO THE CAMERA.
  129.     ' We load that matrix into OpenGL, which then replaces all the OpenGL transformations.  
  130.     glLoadMatrixf (RTInvert (MatrixTranslate (cameraPos#(0), cameraPos#(1), cameraPos#(2)) * cameraMatrix#))
  131.     ' RTInvert is a simple matrix inversion function that ONLY works 
  132.     ' on matrices that are rotations, translations, or some combination
  133.     ' of the two.
  134.     
  135.     ' We now figure out which part of the grid to draw by finding a square area
  136.     ' immediately in front of the camera.
  137.     start# = cameraPos# + cameraMatrix# * vec4 (0, 0, -viewRange / 2, 1)
  138.     startX = start# (0) - viewRange / 2.0
  139.     startY = start# (2) - viewRange / 2.0
  140.  
  141.     ' Draw the grid area
  142.     for x = startX to startX + viewRange - 1
  143.         for y = startY to startY + viewRange - 1
  144.         
  145.             ' Calculate the texture coordinates
  146.             tx# = x * texScale#
  147.             ty# = y * texScale#
  148.  
  149.             ' Draw a grid square.
  150.             glBegin (GL_QUADS)
  151.                 
  152.                 ' By "and"ing the coordinates with the xMask or yMask, we
  153.                 ' are clamping them to that range, giving the map an infinite
  154.                 ' wrap-around effect.
  155.  
  156.                 intensity# = l#(x and xMask)(y and yMask)
  157.                 glColor3f (intensity#, intensity#, intensity#)
  158.                 glTexCoord2f (tx#            , ty#)
  159.                 glVertex3f (x  , h#(x and xMask  )(y and yMask  ), y  )
  160.                 
  161.                 intensity# = l#(x and xMask)(y+1 and yMask)
  162.                 glColor3f (intensity#, intensity#, intensity#)
  163.                 glTexCoord2f (tx#            , ty# + texScale#)
  164.                 glVertex3f (x  , h#(x and xMask  )(y+1 and yMask), y+1)
  165.  
  166.                 intensity# = l#(x+1 and xMask)(y+1 and yMask)
  167.                 glColor3f (intensity#, intensity#, intensity#)
  168.                 glTexCoord2f (tx# + texScale#, ty# + texScale#)
  169.                 glVertex3f (x+1, h#(x+1 and xMask)(y+1 and yMask), y+1)
  170.  
  171.                 intensity# = l#(x+1 and xMask)(y and yMask)
  172.                 glColor3f (intensity#, intensity#, intensity#)
  173.                 glTexCoord2f (tx# + texScale#, ty#)
  174.                 glVertex3f (x+1, h#(x+1 and xMask)(y and yMask  ), y  )
  175.             glEnd ()
  176.         next
  177.     next
  178.     
  179.     ' Draw the text instructions
  180.     DrawText ()
  181.  
  182.     ' Show the result
  183.     SwapBuffers ()
  184.     
  185.     ' Animation
  186.     while SyncTimer (20)
  187.         
  188.         ' Move camera around
  189.         
  190.         ' Rotate the camera by multiplying more rotations into the camera rotation matrix.
  191.         inputX# = 0
  192.         inputY# = 0
  193.         if ScanKeyDown (VK_LEFT)    then inputX# = inputX# + 1 endif
  194.         if ScanKeyDown (VK_RIGHT)   then inputX# = inputX# - 1 endif
  195.         if ScanKeyDown (VK_UP)      then inputY# = inputY# - 1 endif
  196.         if ScanKeyDown (VK_DOWN)    then inputY# = inputY# + 1 endif        
  197.         cameraMatrix# = MatrixRotateY (cameraMatrix# (0)(1) * 0.4) * cameraMatrix# * MatrixRotateZ (inputX#) * MatrixRotateX (inputY#) 
  198.         cameraMatrix# = Orthonormalize (cameraMatrix#)
  199.         ' All these multiplications can produce rounding errors, which can eventually build up
  200.         ' and do weird things.
  201.         ' Therefore we call Orthonormalize, which ensures that the rotation matrix is orthonormal
  202.         ' (meaning it is a proper rotation matrix.)
  203.  
  204.         cameraPos# = cameraPos# + cameraMatrix# * vec4 (0, 0, -.1, 1)
  205.         ' Move the camera forward, by multiplying the forward vector (0, 0, -.1) by the
  206.         ' cameras rotation matrix, and adding it to the position
  207.     wend
  208. wend